package com.andaily.service.impl;

import com.andaily.domain.cooking.CookingAccount;
import com.andaily.domain.cooking.CookingAccountRepository;
import com.andaily.domain.cooking.CookingAccountStatus;
import com.andaily.domain.dto.cooking.CookingAccountDto;
import com.andaily.domain.dto.cooking.CookingAccountOverviewDto;
import com.andaily.domain.dto.user.UserDto;
import com.andaily.domain.shared.Application;
import com.andaily.domain.shared.paginated.PaginatedLoader;
import com.andaily.domain.user.User;
import com.andaily.domain.user.UserRepository;
import com.andaily.service.CookingService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author Shengzhao Li
 */
public class CookingServiceImpl implements CookingService {

    @Autowired
    private CookingAccountRepository repository;
    @Autowired
    private UserRepository userRepository;

    @Override
    public CookingAccountDto loadCookingAccount(String guid) {
        CookingAccountDto dto = new CookingAccountDto();
        if (StringUtils.isNotEmpty(guid)) {
            CookingAccount account = repository.findByGuid(guid);
            dto = new CookingAccountDto(account);
        }
        return dto;
    }

    @Override
    public List<UserDto> loadCookingUsers() {
        List<String> guids = Application.cookingAccountUserGuids();
        List<User> userList = userRepository.findUserByGuids(guids);
        return UserDto.toDtos(userList);
    }

    @Override
    public void persistCookingAccount(CookingAccountDto cookingAccount) {
        CookingAccount account = cookingAccount.instance();
        User creator = userRepository.findByGuid(cookingAccount.getCreatorGuid());
        account.owner(creator);

        if (cookingAccount.isNewly()) {
            repository.saveCookingAccount(account);
        } else {
            repository.updateCookingAccount(account);
        }
    }

    @Override
    public CookingAccountOverviewDto loadCookingAccountOverviewDto(final CookingAccountOverviewDto overviewDto) {
        overviewDto.load(new PaginatedLoader<CookingAccountDto>() {
            @Override
            public List<CookingAccountDto> loadList() {
                List<CookingAccount> accounts = repository.findCookingAccounts(overviewDto);
                return CookingAccountDto.toDtos(accounts);
            }

            @Override
            public int loadTotalSize() {
                return repository.totalCookingAccounts(overviewDto);
            }
        });
        //record total amount
        BigDecimal recordedAmount = repository.amountOfCookingAccountByStatus(CookingAccountStatus.RECORDED);
        BigDecimal finishedAmount = repository.amountOfCookingAccountByStatus(CookingAccountStatus.FINISHED);
        overviewDto.updateAmount(recordedAmount, finishedAmount);
        return overviewDto;
    }

    @Override
    public void archiveCookingAccount(String guid) {
        repository.archiveCookingAccount(guid);
    }
}
